package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
	"github.com/lxn/win"
)

type DbConnFields struct {
	DbHost    string
	DbPort    int
	DbUser    string
	DbPass    string
	DbName    string
	DbCharset string
	WorkDir   string
	FlagList  []OpFlag
}
type OpFlag struct {
	Table     string
	Istime    bool
	Start     string
	Stop      string
	TimeField string
}

func loadConfig(start string, stop string) error {
	var configs interface{}
	fr, err := os.Open("./config.json")
	if err != nil {
		log.AppendText(fmt.Sprint(err.Error() + "配置文件不存在\r\n"))
		return err
	}
	if err = json.NewDecoder(fr).Decode(&configs); err != nil {
		log.AppendText(fmt.Sprint(err.Error() + "配置文件解析错误\r\n"))
		return err
	}
	var chs []chan string
	confs := configs.(map[string]interface{})
	for key, value := range confs {
		if strings.HasPrefix(key, "db_") {
			dbConf := value.(map[string]interface{})
			flagary := make([]OpFlag, 0)
			if dbConf["flag_list"] != nil {
				for _, flagv := range dbConf["flag_list"].([]interface{}) {
					falgs := flagv.(map[string]interface{})
					onflag := OpFlag{
						Table:  falgs["table"].(string),
						Istime: falgs["istime"].(bool),
					}
					if onflag.Istime {
						onflag.Start = start
						onflag.Stop = stop
						if falgs["time_field"] != nil {
							onflag.TimeField = falgs["time_field"].(string)
						}
						if onflag.TimeField == "" {
							onflag.TimeField = "create_time"
						}

					}
					flagary = append(flagary, onflag)
				}
			}
			dbConn := DbConnFields{
				DbHost:    dbConf["db_host"].(string),
				DbPort:    int(dbConf["db_port"].(float64)),
				DbUser:    dbConf["db_user"].(string),
				DbPass:    dbConf["db_pass"].(string),
				DbName:    dbConf["db_name"].(string),
				DbCharset: dbConf["db_charset"].(string),
				WorkDir:   dbConf["db_data"].(string) + "/",
				FlagList:  flagary,
			}
			lch := make(chan string)
			chs = append(chs, lch)
			go ExportOne(dbConn, dbConn.WorkDir, lch, dbConn.FlagList)
		}
	}
	go func() {
		for _, ch := range chs {
			for logg := range ch {
				log.AppendText(logg)
			}
		}
		button.SetEnabled(true)
		button.SetText("开始备份")
		startDate.SetEnabled(true)
		stopDate.SetEnabled(true)
	}()
	return nil
}

var log *walk.TextEdit
var startDate, stopDate *walk.DateEdit
var button *walk.PushButton

func main() {
	var windowMain *walk.MainWindow
	dur, _ := time.ParseDuration("-24h")
	MainWindow{
		Title:    "mysql数据导出工具",
		MinSize:  Size{Width: 600, Height: 800},
		MaxSize:  Size{Width: 600, Height: 800},
		Size:     Size{Width: 600, Height: 800},
		Layout:   VBox{},
		AssignTo: &windowMain,
		Children: []Widget{
			HSplitter{
				Children: []Widget{
					Label{Text: "选择开始时间："},
					DateEdit{AssignTo: &startDate, Date: time.Now().Add(dur)},
					Label{Text: "选择结束时间："},
					DateEdit{AssignTo: &stopDate}, PushButton{
						AssignTo: &button,
						Text:     "开始备份",
						OnClicked: func() {
							button.SetEnabled(false)
							startDate.SetEnabled(false)
							stopDate.SetEnabled(false)
							button.SetText("正在备份...")
							err := loadConfig(startDate.Date().Format("2006-01-02"), stopDate.Date().Format("2006-01-02"))
							if err != nil {
								button.SetEnabled(true)
								button.SetText("开始备份")
								startDate.SetEnabled(true)
								stopDate.SetEnabled(true)
							}

						},
					},
				},
			},
			VSeparator{},
			TextEdit{
				AssignTo: &log,
				ReadOnly: true,
				VScroll:  true},
		},
	}.Create()
	win.SetWindowLong(windowMain.Handle(), win.GWL_STYLE, win.GetWindowLong(windowMain.Handle(), win.GWL_STYLE)&^win.WS_MAXIMIZEBOX&^win.WS_THICKFRAME)
	windowMain.Run()
}
